<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';

import { InputSearch, Tree } from 'ant-design-vue';

import { sysDeptTree } from '#/api/sys/dept';

const props = defineProps({
  value: {
    type: Array,
    default() {
      return [];
    },
  },
});
const emits = defineEmits(['update:value', 'check']);
const treeData = ref([]);
const expandedKeys = ref<(number | string)[]>([]);
const checkedKeys = ref<(number | string)[]>([]);
const autoExpandParent = ref<boolean>(true);
const searchValue = ref('');
const listData = ref<any[]>([]); // 新增 listData
const flattenTree = (tree: Array<any>): any[] => {
  const result: any[] = [];

  const traverse = (nodes: Array<any>, parentKey?: number | string) => {
    nodes.forEach((node) => {
      const { children, ...rest } = node;
      result.push({ ...rest, parentKey });
      if (children && children.length > 0) {
        traverse(children, node.id);
      }
    });
  };

  traverse(tree);
  return result;
};

onMounted(() => {
  sysDeptTree({}).then((res) => {
    treeData.value = res;
    listData.value = flattenTree(res);
  });
});
const getParentKey = (
  key: number | string,
  tree: Array<any>,
): number | string | undefined => {
  if (!tree || tree.length === 0) return undefined;

  for (const node of tree) {
    if (node.children && node.children.some((item: any) => item.id === key)) {
      return node.id; // 找到父节点，直接返回
    }
    if (node.children) {
      const parentKey = getParentKey(key, node.children); // 递归查找
      if (parentKey !== undefined) {
        return parentKey; // 子树中找到，返回结果
      }
    }
  }
  return undefined; // 未找到目标节点
};
const onExpand = (keys: any) => {
  expandedKeys.value = keys;
  autoExpandParent.value = false;
};
const onCheck = (mCheckedKeys: any) => {
  checkedKeys.value = mCheckedKeys;
  emits('update:value', mCheckedKeys);
  emits('check', mCheckedKeys);
};

watch(
  () => props.value,
  (value) => {
    if (value) {
      checkedKeys.value = value as any;
    }
  },
  {
    immediate: true,
  },
);
watch(searchValue, (value) => {
  const expanded = listData.value
    .map((item: any) => {
      if (item.name.includes(value)) {
        return getParentKey(item.id, treeData.value);
      }
      return null;
    })
    .filter((item, i, self) => item && self.indexOf(item) === i);
  expandedKeys.value = expanded as any;
  searchValue.value = value;
  autoExpandParent.value = true;
});
watch(treeData, (newTreeData) => {
  listData.value = flattenTree(newTreeData); // 更新 listData
});
</script>
<template>
  <InputSearch
    v-model:value="searchValue"
    style="margin-bottom: 8px"
    placeholder="关键字搜索"
  />
  <Tree
    checkable
    :tree-data="treeData"
    :show-line="true"
    @expand="onExpand"
    @check="onCheck"
    :selectable="false"
    :expanded-keys="expandedKeys"
    :checked-keys="checkedKeys"
    :auto-expand-parent="autoExpandParent"
    :field-names="{ title: 'name', key: 'id' }"
  >
    <template #title="{ name: title }">
      <span v-if="title.includes(searchValue)">
        {{ title.substring(0, title.indexOf(searchValue)) }}
        <span style="color: #f50">{{ searchValue }}</span>
        {{ title.substring(title.indexOf(searchValue) + searchValue.length) }}
      </span>
      <span v-else>{{ title }}</span>
    </template>
  </Tree>
</template>
